﻿using System;
using System.Collections.Generic;
using System.Drawing.Imaging;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Net.NetworkInformation;
using System.Text;
using System.Threading.Tasks;
using ChoJuRating.View;
using ChongJu.CloudService;
using ChongJu.EventManager.ModelChange;
using ChongJu.GlobalInfo;
using ChongJu.ImageAnalyze.XCDNN;
using ChongJu.ModelManager;
using GalaSoft.MvvmLight.Threading;
using Microsoft.Practices.Prism.Commands;
using Public.Logger;
using Public.MvvmBase;
using Public.Tools;
using System.Timers;
using System.Windows;
using ChongJu.Camera;
using System.Windows.Media;
using ChongJu.ModelManager.Rating;
using System.Threading;
using ChongJu.ImageAnalyze;
using ChoJu.Single.DAL;

namespace ChoJu.Single.ViewModel
{
    public class CollectVM : PropertyChangedBase
    {
        private IAnalyzeBase _tbcoAnalyze;

        private System.Timers.Timer _timer;
        private System.Timers.Timer _timerPing;

        private CloudService _cloud;

        private string _filePath;
        private SaveInfo save = new SaveInfo();
        private bool _isUp = true; //是否是上层图片

        public CollectVM()
        {
            Camera.Instance.ImageCallBackEvent += Instance_ImageCallBackEvent;
            ExchangeModEvent.ExchangeModEventReport += ExchangeModEvent_ExchangeModEventReport;

            StartCommand = new DelegateCommand(StartFunction);
            StopCommand = new DelegateCommand(StopFunction);
            StopBatchCommand = new DelegateCommand(StopBatchFunction);
            UpBottomCommand = new DelegateCommand(UpBottomFunction);

            Variety = GlobalVar.SiteInfo?.VarietyName;

            _timerPing = new System.Timers.Timer(3000);
            _timerPing.Elapsed += _timerPing_Elapsed;
            _timerPing.Enabled = true;

            if (GlobalVar.GlobalParamer.IsBottom == true)
            {
                _isUp = false;
                ViewImgIdx = Visibility.Visible;
            }
            else
            {
                _isUp = true;
                ViewImgIdx = Visibility.Collapsed;
            }
            ImgIdx = "上";

            _timer = new System.Timers.Timer(1000);
            _timer.Elapsed += _timer_Elapsed;
            Task.Factory.StartNew(() =>
            {
                while (InitModel.Model == false)
                    Thread.Sleep(1000 * 1);

                Init();
            });
        }


        #region Property

        /// <summary>
        /// 当前工作模式
        /// </summary>
        public RunTypeEnum CurrentWorkMod
        {
            get
            {
                return GlobalVar.CurrentRunType;
            }
            set
            {
                GlobalVar.CurrentRunType = value;
                OnPropertyChanged(() => CurrentWorkMod);
            }
        }

        /// <summary>
        /// 当前烟叶图片
        /// </summary>
        public object CurrentImage
        {
            get { return _currentImage; }
            set { _currentImage = value; OnPropertyChanged(() => CurrentImage); }
        }
        private object _currentImage;

        /// <summary>
        /// 当前烟叶重量
        /// </summary>
        public object CurrentWeight
        {
            get { return _currentWeight; }
            set { _currentWeight = value; OnPropertyChanged(() => CurrentWeight); }
        }
        private object _currentWeight;

        //UI实时显示图片的数据流
        private MemoryStream _stream = null;

        /// <summary>
        /// 是否运行中
        /// </summary>
        public bool IsRunning
        {
            get { return _isRunning; }
            set { _isRunning = value; OnPropertyChanged(() => IsRunning); }
        }
        private bool _isRunning;

        /// <summary>
        /// 城市
        /// </summary>
        public string City
        {
            get { return _city; }
            set { _city = value; OnPropertyChanged(() => City); }
        }
        private string _city;

        /// <summary>
        /// 品种
        /// </summary>
        public string Variety
        {
            get { return _variety; }
            set
            {
                _variety = value?.Replace("System.Windows.Controls.ComboBoxItem: ", "");
                OnPropertyChanged(() => Variety);
            }
        }
        private string _variety;

        /// <summary>
        /// 部位
        /// </summary>
        public bool[] Part
        {
            get { return _part; }
            set { _part = value; OnPropertyChanged(() => Part); }
        }
        private bool[] _part = { false, true, false };

        public string PartStr
        {
            get
            {
                string tmp = Part[0] ? "上" : string.Empty;
                tmp += Part[1] ? "中" : string.Empty;
                tmp += Part[2] ? "下" : string.Empty;
                return tmp;
            }
            set
            {
                Part[0] = value.Contains("上");
                Part[1] = value.Contains("中");
                Part[2] = value.Contains("下");
            }
        }

        /// <summary>
        /// 等级
        /// </summary>
        public string Level
        {
            get
            {
                if (string.IsNullOrWhiteSpace(_level) == false)
                    return _level;
                return _level;
            }
            set
            {
                _level = value;
                OnPropertyChanged(() => Level);
            }
        }
        private string _level;

        /// <summary>
        /// 显示结束采集批次按钮
        /// </summary>
        public Visibility ViewEndBatchButton
        {
            get
            {
                if (save.IsComplate == true)
                    return Visibility.Collapsed;
                else
                    return Visibility.Collapsed;
            }
            set { }
        }

        /// <summary>
        /// 网络延时
        /// </summary>
        public long BosNetTime
        {
            get { return _bosNetTime; }
            set { _bosNetTime = value; OnPropertyChanged(() => BosNetTime); }
        }
        private long _bosNetTime;

        /// <summary>
        /// 是否在上传
        /// </summary>
        public bool IsUpload
        {
            get { return _isUpload; }
            set { _isUpload = value; OnPropertyChanged(() => IsUpload); }
        }
        private bool _isUpload;


        public string CollectNo
        {
            get { return _collectNo; }
            set { _collectNo = value; OnPropertyChanged(() => CollectNo); }
        }
        private string _collectNo;

        public int UploadCount
        {
            get { return _uploadCount; }
            set { _uploadCount = value; OnPropertyChanged(() => UploadCount); }
        }
        private int _uploadCount;

        public int UploadTotal
        {
            get { return _uploadTotal; }
            set { _uploadTotal = value; OnPropertyChanged(() => UploadTotal); }
        }
        private int _uploadTotal;


        public double Percent
        {
            get { return _percent; }
            set { _percent = value; OnPropertyChanged(() => Percent); }
        }
        private double _percent;

        /// <summary>
        /// 提示信息
        /// </summary>
        public string Msg
        {
            get { return _msg; }
            set { _msg = value; OnPropertyChanged(() => Msg); }
        }
        private string _msg;


        public Visibility ViewImgIdx
        {
            get { return _viewImgIdx; }
            set { _viewImgIdx = value; OnPropertyChanged(() => ViewImgIdx); }
        }
        private Visibility _viewImgIdx;

        public string ImgIdx
        {
            get { return _imgIdx; }
            set { _imgIdx = value; OnPropertyChanged(() => ImgIdx); }
        }
        private string _imgIdx;


        #endregion


        #region Command

        public DelegateCommand StartCommand { get; }

        public DelegateCommand StopCommand { get; }

        public DelegateCommand SureLevelCommand { get; }

        public DelegateCommand CreateBatchCommand { get; }

        public DelegateCommand StopBatchCommand { get; }

        public DelegateCommand UpBottomCommand { get; }

        #endregion


        #region Function


        private void StartFunction()
        {
            if (save == null || _cloud == null)
            {
                CJMsgBox.ShowDialog("初始化未完成，稍等");
                return;
            }

            if (string.IsNullOrEmpty(save.CollectNo) == true || save.IsComplate == true)
            {
                save.CollectNo = _cloud.GetBatchNo(GlobalVar.SiteInfo.AreaName, GlobalVar.SiteInfo.SiteName, GlobalVar.SiteInfo.VarietyName, PartStr);
                if (string.IsNullOrWhiteSpace(save.CollectNo) == true)
                {
                    CJMsgBox.ShowDialog("创建采集号失败");
                    return;
                }
                save.Data = new List<ImageInfo>();
                save.IsComplate = false;
                CollectNo = save.CollectNo;
                UploadCount = 0;
                UploadTotal = 0;
                Percent = 0;
                File.WriteAllText(_filePath, Tool.ObjectToJson(save));
            }

            if (string.IsNullOrWhiteSpace(Level))
            {
                CJMsgBox.ShowDialog("请先设置等级");
                return;
            }

            GlobalVar.CurrentRunType = RunTypeEnum.Collection;
            IsRunning = true;

            if (_timer.Enabled == false)
                _timer.Enabled = true;
        }

        private void StopFunction()
        {
            IsRunning = false;
            GlobalVar.CurrentRunType = RunTypeEnum.None;
            ExchangeModEvent.OnExchangeMod(RunTypeEnum.None);
        }

        private void StopBatchFunction()
        {
            try
            {
                if (IsRunning == true)
                {
                    CJMsgBox.ShowDialog("请先停止设备！");
                    return;
                }

                CurrentWorkMod = RunTypeEnum.None;
                GlobalVar.CurrentRunType = RunTypeEnum.None;
                ExchangeModEvent.OnExchangeMod(RunTypeEnum.None);

                var res = _cloud.EndImageCollect(save.CollectNo, "each");
                if (string.IsNullOrWhiteSpace(res) == false)
                {
                    CJMsgBox.ShowDialog(res);
                    return;
                }
                save.IsComplate = true;
                save.Data?.ForEach(f => f.Image = null);
                File.WriteAllText(_filePath, Tool.ObjectToJson(save));

                _timer.Enabled = false;
                CJMsgBox.ShowDialog("完成采集！！！");
            }
            catch (Exception ex)
            {
                Logger.Error("结束采集批次异常：", ex);
            }
        }

        private void UpBottomFunction()
        {
            if (ImgIdx == "上")
                ImgIdx = "下";
            else
                ImgIdx = "上";
        }
        #endregion


        #region Event 

        private void Instance_ImageCallBackEvent(Bitmap bitmap, DateTime tm)
        {
            if (GlobalVar.CurrentRunType != RunTypeEnum.Collection)
                return;

            try
            {
                ImageInfo info = new ImageInfo()
                {
                    Image = bitmap,
                    LevelCode = _isUp ? Level : $"{Level}_d",
                    CollectNo = save.CollectNo,
                    CreateTime = DateTime.Now,
                    IsUpload = false,
                    IsUp = _isUp
                };
                SaveImage(info, _isUp);

                if (GlobalVar.GlobalParamer.IsBottom == true)
                {
                    if (_isUp == true)
                    {
                        _isUp = false;
                        Camera.Instance.Stop();
                        Camera.Instance.OpneLine1CloseLine2();
                        Camera.Instance.Start();
                        Camera.Instance.SetTriggerByLine0();
                    }
                    else
                    {
                        _isUp = true;
                        Camera.Instance.Stop();
                        Camera.Instance.OpneLine2CloseLine1();
                        Camera.Instance.Start();
                        Camera.Instance.SetTriggerBySoftware();
                        Camera.Instance.TakeOne();
                    }
                }
            }
            catch (Exception ex)
            {
                Logger.Error("处理采集图片异常", ex);
            }
        }

        private void ExchangeModEvent_ExchangeModEventReport(RunTypeEnum obj)
        {
            CurrentWorkMod = obj;
        }


        private void _timer_Elapsed(object sender, ElapsedEventArgs e)
        {
            if (IsUpload == true)
                return;

            IsUpload = true;
            try
            {
                //批次结束 且上传完成
                if (save.Data.Exists(q => q.IsUpload == false) == false &&
                    string.IsNullOrWhiteSpace(save.CollectNo) == true)
                {
                    _timer.Enabled = false;
                    return;
                }

                var find = save.Data.Find(f => f.IsUpload == false);
                if (find == null)
                    return;

                var img = new Bitmap(find.Path);
                var bytes = Tool.BitmapToBytes(img);
                var msg = _cloud.UploadImage(bytes, GlobalVar.SiteInfo.SiteName, save.CollectNo, find.LevelCode, find.Weight, 0, "each", find.ImageName);
                if (msg != null)
                {
                    Msg = msg;
                    return;
                }
                Msg = string.Empty;

                find.IsUpload = true;
                find.Image = null;
                File.WriteAllText(_filePath, Tool.ObjectToJson(save));
                if (find.IsUp == true)
                    UploadCount += 1;
                Percent = Math.Round((double)UploadCount / (double)UploadTotal, 3) * 100;
            }
            catch (Exception ex)
            {
                Logger.Error("上传采集信息异常：", ex);
            }
            finally
            {
                IsUpload = false;
            }
        }

        private void _timerPing_Elapsed(object sender, ElapsedEventArgs e)
        {

            try
            {
                var addr = "1.95.89.249";
                Ping ping = new Ping();
                BosNetTime = ping.Send(addr, 3000).RoundtripTime;
            }
            catch (Exception ex)
            {
                BosNetTime = -1;
            }
        }

        #endregion


        #region private function

        private bool Init()
        {
            try
            {
                _tbcoAnalyze = AnalyzeService.Instance.GetFrist()?.Analyze;
                _cloud = new CloudService();
                var dir = Path.Combine(AppContext.BaseDirectory, "Data");
                if (Directory.Exists(dir) == false)
                    Directory.CreateDirectory(dir);
                _filePath = Path.Combine(AppContext.BaseDirectory, "Data", "collect.txt");
                if (File.Exists(_filePath) == false)
                    save = new SaveInfo();
                else
                {
                    save = Tool.JsonToObject<SaveInfo>(Tool.Read(_filePath));
                    if (save == null)
                    {
                        save = new SaveInfo();
                        File.Delete(_filePath);
                    }
                }

                if (save.Data.Exists(e => e.IsUpload == false) == true)
                    _timer.Enabled = true;
                else
                    _timer.Enabled = false;

                UploadCount = save.Data.Count(c => c.IsUpload == true);
                UploadTotal = save.Data.Count;
                Percent = Math.Round((double)UploadCount / (double)UploadTotal, 3) * 100;
                CollectNo = save.CollectNo;
                return true;
            }
            catch (Exception ex)
            {
                Logger.Error("采集初始化异常：", ex);
                return false;
            }
        }

        private void SaveImage(ImageInfo imgInfo, bool isUp = true)
        {
            Task.Factory.StartNew(() =>
            {
                Bitmap bitmap = imgInfo.Image;
                IntPtr _temp = IntPtr.Zero;
                int w = 0;
                int h = 0;
                int step = 0;
                double angle = 0;
                int x1 = 0;
                int y1 = 0;
                int w1 = 0;
                int h1 = 0;
                try
                {
                    imgInfo.Weight = (float)WeightDal.Instance.GetWeight();
                    BitmapData bitmapdata = bitmap.LockBits(new Rectangle(0, 0, bitmap.Width, bitmap.Height), ImageLockMode.ReadWrite, bitmap.PixelFormat);
                    _temp = _tbcoAnalyze.GetSegmentationImg(
                        bitmapdata.Width,
                        bitmapdata.Height,
                        bitmapdata.Scan0,
                        bitmapdata.Stride,
                        ref w,
                        ref h,
                        ref step,
                        ref angle,
                        ref x1, ref y1, ref w1, ref h1, isUp);

                    //保存图片到本地磁盘
                    var dist = DriveInfo.GetDrives().ToList();
                    var p = dist.Exists(e => e.Name.ToLower().StartsWith("d:")) ? "D" : "C";

                    var dir = Path.Combine($"{p}:\\Collection", save.CollectNo, imgInfo.LevelCode);
                    if (Directory.Exists(dir) == false)
                        Directory.CreateDirectory(dir);
                    var tm = string.Empty;
                    if (GlobalVar.GlobalParamer.IsBottom == true & isUp == true)
                        save.Data.Last().CreateTime.ToString("yyyyMMddHHmmssfff");
                    else
                        tm = imgInfo.CreateTime.ToString("yyyyMMddHHmmssfff");

                    var name = $"{tm}{(isUp == false ? "_down" : null)}_{imgInfo.Weight}";
                    var file = Path.Combine(dir, $"{name}.png");
                    imgInfo.Path = file;
                    imgInfo.ImageName = name;

                    Bitmap result = new Bitmap(w, h, step, bitmapdata.PixelFormat, _temp);
                    result.Save(file, ImageFormat.Png);

                    //保存原图
                    var dirOri = Path.Combine($"{p}:\\CollectionOriginal\\{DateTime.Now.ToString("yyyy-MM-dd")}", save.CollectNo, (isUp ? imgInfo.LevelCode : $"{imgInfo.LevelCode}_d"));
                    if (Directory.Exists(dirOri) == false)
                        Directory.CreateDirectory(dirOri);
                    var original = Path.Combine(dirOri, $"{name}.png");
                    imgInfo.Image.Save(original, ImageFormat.Png);

                    //保存图片信息到内存
                    save.Data.Add(imgInfo);
                    File.WriteAllText(_filePath, Tool.ObjectToJson(save));
                    if (isUp == true)
                        UploadTotal += 1;
                    Percent = Math.Round((double)UploadCount / (double)UploadTotal, 3) * 100;

                    CurrentWeight = Math.Round(imgInfo.Weight, 2);
                    bitmap.UnlockBits(bitmapdata);

                    if (ImgIdx == "上" & isUp == true || ImgIdx == "下" & isUp == false)
                        ViewImageUI(bitmap);


                    imgInfo.Image?.Dispose(); //image不能保存到数据库
                    result.Dispose();
                }
                catch (Exception ex)
                {
                    Logger.Error($"保存采集图片异常 w:{w} h:{h}", ex);
                }
                finally
                {
                    bitmap?.Dispose();
                    _tbcoAnalyze?.FreeImage(_temp);
                }
            });
        }

        private void ViewImageUI(Bitmap image)
        {
            try
            {
                if (_stream != null)
                    _stream.Dispose();

                _stream = new MemoryStream();
                var compress = new SaveImage().ImageCompress(image);
                if (compress == null)
                    return;

                compress.Save(_stream, ImageFormat.Png);
                DispatcherHelper.CheckBeginInvokeOnUI(() =>
                {
                    try
                    {
                        if (_stream != null)
                            CurrentImage = (ImageSource)new ImageSourceConverter().ConvertFrom(_stream);

                        compress?.Dispose();
                        image?.Dispose();
                    }
                    catch (Exception ex)
                    {
                        Logger.Error("UI显示图片异常,内部调用", ex);
                    }
                });
            }
            catch (Exception ex)
            {
                Logger.Error("UI显示图片异常", ex);
            }
        }


        #endregion
    }


    public class ImageInfo
    {
        public Bitmap Image { get; set; }

        public string Path { get; set; }

        public string LevelCode { get; set; }

        public string LevelName { get; set; }

        public float Weight { get; set; }

        /// <summary>
        /// 图片上传标志
        /// </summary>
        public bool IsUpload { get; set; }

        public string CollectNo { get; set; }

        public DateTime CreateTime { get; set; }

        /// <summary>
        /// 图片文件名称
        /// </summary>
        public string ImageName { get; set; }

        public bool IsUp { get; set; }
    }

    public class SaveInfo
    {
        public string CollectNo { get; set; }

        public bool IsComplate { get; set; }

        public List<ImageInfo> Data { get; set; } = new List<ImageInfo>();
    }
}
